package Cryptographic;

import java.io.ByteArrayOutputStream;

import Verifier.GeneralUtil;
	
	/**
	 * 
	 * @author Or Stern
	 *
	 */
	public class RandomOracle {
		PRG prg;
		HashFunction hashFunction;
		int nout;
		
		/**
		 * 
		 * @param hash  The Hash Function which will be used in the random oracle.
		 * @param nout The length of the output in bits.
		 */
		public RandomOracle(HashFunction hash, int nout)
		{
			hashFunction = hash;
			this.nout = nout;
			prg = new PRG(hash);
		}
		
		/**
		 * Generates the random oracle
		 * @param d The byte array which the RO will be generated for.
		 * @return Byte array containing the bit representation of the RO on d.
		 * @throws Exception when no data can be generated by the oracle.
		 */
		public byte[] compute(byte[] d) throws Exception
		{
			ByteArrayOutputStream sBeforeHash = new ByteArrayOutputStream();
			byte[] a;
			try
			{
				sBeforeHash.write(GeneralUtil.intToByteArray(nout));
				sBeforeHash.write(d);
				
				byte[] s = hashFunction.compute(sBeforeHash.toByteArray());
				
				int noutBytes = (nout + 7) / 8; 
				
				a = prg.compute(s, 0, noutBytes -1);
				if ((nout % 8) != 0)
				{
					/* set the first zeroBits to zero*/
					a[0] =  (byte) (a[0] & (0xFF >>> (8 - (nout % 8))));
					
				}
			} catch (Exception e) {
				throw new Exception("A problem occured while computing the Random Oracle output\n" + e.getMessage());
			}
			
			return a;
		}
}
